const Path = require('path');
const Cp = require('child_process');
const Webpack = require('webpack');
const Cssnano = require('cssnano');

function getGitRevision() {
  const gitContent = {
    version: Cp.execSync('git describe --tags --always', { encoding: 'utf8' }),
    commithash: Cp.execSync('git rev-list --max-count=1 --no-merges HEAD', {
      encoding: 'utf8',
    }),
    branch: Cp.execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }),
  };

  return gitContent;
}

function resolve(dir) {
  return Path.join(__dirname, dir);
}

module.exports = {
  lintOnSave: process.env.NODE_ENV === 'development',
  productionSourceMap: false,
  devServer: {
    port: 5080,
    disableHostCheck: true,
    overlay: {
      warnings: true,
      errors: true,
    },
  },
  css: {
    loaderOptions: {
      less: {
        lessOptions: {
          javascriptEnabled: true,
          modifyVars: {
            hack: `true; @import "./src/assets/style/vant.less";`,
          },
        },
      },
      sass: {
        additionalData: `@import "./src/assets/style/basic/mixins.scss"; @import "./src/assets/style/basic/variables.scss";`,
      },
    },
  },
  chainWebpack(config) {
    config.resolve.alias.set('@', resolve('src'));
    config.performance.set('hints', false);
    config.module
      .rule('images')
      .use('url-loader')
      .loader('url-loader')
      .tap((options) => Object.assign(options, { limit: 10240 }));
    config.plugin('DefinePlugin').use(
      new Webpack.DefinePlugin({
        VERSION: JSON.stringify(getGitRevision().version),
        COMMITHASH: JSON.stringify(getGitRevision().commithash),
        BRANCH: JSON.stringify(getGitRevision().branch),
        BUILDDATE: JSON.stringify(new Date()),
      }),
    );
    config.when(process.env.NODE_ENV === 'development', () => {
      config.merge({ devtool: 'source-map' });
      config
        .plugin('CaseSensitivePathsPlugin')
        .use(require.resolve('case-sensitive-paths-webpack-plugin'));
      config
        .plugin('HardSourceWebpackPlugin')
        .use(require.resolve('hard-source-webpack-plugin-fixed-hashbug'));
    });
    config.when(process.env.NODE_ENV === 'production', () => {
      config.optimization.minimizer('terser').use(require.resolve('terser-webpack-plugin'), [
        {
          parallel: true,
          test: /\.js(\?.*)?$/i,
          terserOptions: {
            compress: {
              drop_debugger: true,
              pure_funcs: ['console.log'],
            },
            warnings: false,
            output: {
              keep_quoted_props: true,
            },
          },
        },
      ]);
      config.optimization
        .minimizer('css')
        .use(require.resolve('optimize-css-assets-webpack-plugin'), [
          {
            assetNameRegExp: /\.css$/g,
            cssProcessorOptions: {
              safe: true,
              autoprefixer: false,
              discardComments: {
                removeAll: true,
              },
            },
            cssProcessor: Cssnano,
            cssProcessorPluginOptions: {
              preset: [
                'default',
                { discardComments: { removeAll: true }, normalizeUnicode: false },
              ],
            },
            canPrint: true,
          },
        ]);
      config.optimization.splitChunks({
        chunks: 'all',
        minSize: 20000,
        minChunks: 2,
        maxAsyncRequests: 5,
        maxInitialRequests: 3,
        name: true,
        automaticNameDelimiter: '-',
        cacheGroups: {
          libs: {
            chunks: 'initial',
            test: /[\\/]node_modules[\\/]/,
            name: 'chunk-libs',
            priority: 10,
            enforce: true,
            reuseExistingChunk: true,
          },
          commons: {
            test: /common\/|components\/|utils\//,
            name: 'chunk-commons',
            chunks: 'initial',
            minChunks: 3,
            priority: 5,
            enforce: true,
            reuseExistingChunk: true,
          },
          vantUI: {
            test: /[\\/]node_modules[\\/]_?vant(.*)/,
            name: 'chunk-vant',
            priority: 20,
            enforce: true,
            chunks: 'all',
            reuseExistingChunk: true,
          },
          styles: {
            name: 'styles',
            test: /\.(sa|sc|c)ss$/,
            chunks: 'all',
            enforce: true,
            reuseExistingChunk: true,
          },
        },
      });
      config.optimization.runtimeChunk('single');
    });
  },
  publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
};
